home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / glass / glass.lha / GLASS / tm / tmexpr.c < prev    next >
C/C++ Source or Header  |  1990-11-06  |  5KB  |  296 lines

  1. /* 
  2.    Copyright (C) 1990 C van Reewijk, email: dutentb.uucp!reeuwijk
  3.  
  4. This file is part of GLASS.
  5.  
  6. GLASS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GLASS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GLASS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* File: tmexpr.c
  21.  *
  22.  * Handle expressions.
  23.  */
  24.  
  25. /* Standard UNIX libraries and expressions */
  26. #include <stdio.h>
  27. #include <ctype.h>
  28.  
  29. /* tm library */
  30. #include <tmc.h>
  31.  
  32. /* local definitions */
  33. #include "tmdefs.h"
  34.  
  35. #include "tmds.h"
  36. #include "tmstring.h"
  37. #include "debug.h"
  38. #include "tmerror.h"
  39. #include "tmexpr.h"
  40. #include "tmglobal.h"
  41. #include "tmmisc.h"
  42.  
  43. /* integer expression evaluation.
  44.  * All these functions evaluate a set of operators at one
  45.  * priority level, set a value pointed to by a passed pointer to
  46.  * the evaluated value, and return a pointer to the remaining string.
  47.  *
  48.  * Priorities (in order of increasing binding power:
  49.  *
  50.  * & |
  51.  * < <= > >= == !=
  52.  * + -
  53.  * * / %
  54.  * + - ~ ! (unary)
  55.  */
  56.  
  57. static char *evalbool();
  58.  
  59. /* Evaluate integer constants and '()'. */
  60. static char *evalconst( x, vp )
  61.  register char *x;
  62.  long *vp;
  63. {
  64.     string buf;
  65.     char *bufp;
  66.     char *s;
  67.  
  68.     while( isspace( *x ) ) x++;
  69.     if( *x == ORBRAC ){
  70.     s = evalbool( x+1, vp );
  71.     while( isspace( *s ) ) s++;
  72.     if( *s != CRBRAC ){
  73.         return( x );
  74.     }
  75.     else{
  76.         return( s+1 );
  77.     }
  78.     }
  79.     buf = new_string( x );
  80.     bufp = buf;
  81.     while( isdigit( *x ) ){
  82.     *bufp++ = *x++;
  83.     }
  84.     *bufp = '\0';
  85.     if( buf[0] == '\0' ){
  86.     line_error( BADEXPR );
  87.     *vp = 0;
  88.     }
  89.     else{
  90.     *vp = atoi( buf );
  91.     }
  92.     fre_string( buf );
  93.     return( x );
  94. }
  95.  
  96. /* Evaluate unary operators. */
  97. static char *evalun( x, vp )
  98.  register char *x;
  99.  long *vp;
  100. {
  101.     char *s;
  102.     long v;
  103.  
  104.     while( isspace( *x ) ) x++;
  105.     if( *x == '-' ){
  106.     s = evalun( x+1, &v );
  107.     *vp = -v;
  108.     return( s );
  109.     }
  110.     if( *x == '!' ){
  111.     s = evalun( x+1, &v );
  112.     *vp = !v;
  113.     return( s );
  114.     }
  115.     if( *x == '+' ){
  116.     return( evalun( x+1, vp ) );
  117.     }
  118.     return( evalconst( x, vp) );
  119. }
  120.  
  121. /* Evaluate product operators. */
  122. static char *evalprod( x, vp )
  123.  register char *x;
  124.  long *vp;
  125. {
  126.     char *s;
  127.     long v1;
  128.     long v2;
  129.  
  130.     while( isspace( *x ) ) x++;
  131.     s = evalun( x, &v1 );
  132.     if( s == x ){
  133.     *vp = 0;
  134.     return( x );
  135.     }
  136.     while( isspace( *s ) ) s++;
  137.     if( *s == '*' ){
  138.     s = evalprod( s+1, &v2 );
  139.     *vp = v1*v2;
  140.     return( s );
  141.     }
  142.     if( *s == '/' ){
  143.     s = evalprod( s+1, &v2 );
  144.     if( v2 == 0 ){
  145.         *vp = ~(-1);
  146.     }
  147.     else {
  148.         *vp = v1/v2;
  149.     }
  150.     return( s );
  151.     }
  152.     if( *s == '%' ){
  153.     s = evalprod( s+1, &v2 );
  154.     if( v2 == 0 ){
  155.         *vp = ~(-1);
  156.     }
  157.     else {
  158.         *vp = v1%v2;
  159.     }
  160.     return( s );
  161.     }
  162.     *vp = v1;
  163.     return( s );
  164. }
  165.  
  166. /* Evaluate sum operators. */
  167. static char *evalsum( x, vp )
  168.  register char *x;
  169.  long *vp;
  170. {
  171.     char *s;
  172.     long v1;
  173.     long v2;
  174.  
  175.     while( isspace( *x ) ) x++;
  176.     s = evalprod( x, &v1 );
  177.     if( s == x ){
  178.     *vp = 0;
  179.     return( x );
  180.     }
  181.     while( isspace( *s ) ) s++;
  182.     if( *s == '+' ){
  183.     s = evalsum( s+1, &v2 );
  184.     *vp = v1+v2;
  185.     return( s );
  186.     }
  187.     if( *s == '-' ){
  188.     s = evalsum( s+1, &v2 );
  189.     *vp = v1-v2;
  190.     return( s );
  191.     }
  192.     *vp = v1;
  193.     return( s );
  194. }
  195.  
  196. /* Evaluate compare operators. */
  197. static char *evalcmp( x, vp )
  198.  register char *x;
  199.  long *vp;
  200. {
  201.     char *s;
  202.     long v1;
  203.     long v2;
  204.  
  205.     while( isspace( *x ) ) x++;
  206.     s = evalsum( x, &v1 );
  207.     if( s == x ){
  208.     *vp = 0;
  209.     return( x );
  210.     }
  211.     while( isspace( *s ) ) s++;
  212.     if( s[0] == '!' && s[1] == '=' ){
  213.     s = evalsum( s+2, &v2 );
  214.     *vp = (v1!=v2);
  215.     return( s );
  216.     }
  217.     if( s[0] == '=' && s[1] == '=' ){
  218.     s = evalsum( s+2, &v2 );
  219.     *vp = (v1==v2);
  220.     return( s );
  221.     }
  222.     if( s[0] == '<' && s[1] == '=' ){
  223.     s = evalsum( s+2, &v2 );
  224.     *vp = (v1<=v2);
  225.     return( s );
  226.     }
  227.     if( s[0] == '<' ){
  228.     s = evalsum( s+1, &v2 );
  229.     *vp = (v1<v2);
  230.     return( s );
  231.     }
  232.     if( s[0] == '>' && s[1] == '=' ){
  233.     s = evalsum( s+2, &v2 );
  234.     *vp = (v1>=v2);
  235.     return( s );
  236.     }
  237.     if( s[0] == '>' ){
  238.     s = evalsum( s+1, &v2 );
  239.     *vp = (v1>v2);
  240.     return( s );
  241.     }
  242.     *vp = v1;
  243.     return( s );
  244. }
  245.  
  246. /* Evaluate boolean binary operators. */
  247. static char *evalbool( x, vp )
  248.  register char *x;
  249.  long *vp;
  250. {
  251.     char *s;
  252.     long v1;
  253.     long v2;
  254.  
  255.     s = evalcmp( x, &v1 );
  256.     while( isspace( *s ) ) s++;
  257.     if( s[0] == '&' ){
  258.     s = evalbool( s+1, &v2 );
  259.     *vp = v1 && v2;
  260.     return( s );
  261.     }
  262.     if( s[0] == '|' ){
  263.     s = evalbool( s+1, &v2 );
  264.     *vp = v1 || v2;
  265.     return( s );
  266.     }
  267.     *vp = v1;
  268.     return( s );
  269. }
  270.  
  271. /* Given a string 'x' containing a numerical expression,
  272.  * evaluate it, and construct a string from the resulting integer.
  273.  */
  274. char *evalexpr( x )
  275.  string x;
  276. {
  277.     char buf[NUMBUFSIZE];
  278.     char *s;
  279.     long v;
  280.  
  281.     if( fntr ){
  282.     fprintf( tracestream, "evaluating expression $[%s]\n", x );
  283.     }
  284.     s =  evalbool( x, &v );
  285.     while( isspace( *s ) ) s++;
  286.     if( *s != '\0' ){
  287.     (void) strcpy( errarg, s );
  288.     line_error( BADEXPR );
  289.     }
  290.     (void) sprintf( buf, "%ld", v );
  291.     if( fntr ){
  292.     fprintf( tracestream, "expression value: '%s'\n", buf );
  293.     }
  294.     return( new_string( buf ) );
  295. }
  296.